package tom.client;

import java.util.Map;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DoubleBox;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.gwtext.client.widgets.form.ComboBox;

public abstract class DataForm extends AbsolutePanel {

	protected final Label lbCode;
	protected final TextBox txtCode;
	protected final Button btnDelete;
	protected final Button btnSearch;
	protected final Button btnSave;
	protected final HorizontalPanel horizontalPanel;
	private Button btnReport;
	private int mode = 0; // 0=clear 1=browse 2=update 3=insert

	public void open(String code) {
		txtCode.setText(code);
		refresh();
	}

	public String getCode() {
		return txtCode.getText();
	}

	public void setMode(int mode) {
		this.mode = mode;
		if (mode == 0) { // clear
			btnSave.setEnabled(false);
			btnDelete.setEnabled(false);
			btnSearch.setEnabled(true);
			txtCode.setReadOnly(false);
			txtCode.setFocus(true);
			txtCode.setText(null);
			modeBox.setSelectedIndex(mode);
		} else if (mode == 1 && txtCode.getText() != null) { // browse
			btnSave.setEnabled(true);
			btnDelete.setEnabled(true);
			btnSearch.setEnabled(true);
			txtCode.setReadOnly(true);
			txtCode.setFocus(true);
			modeBox.setSelectedIndex(mode);
		} else if (mode == 2 && txtCode.getText() != null) { // update
			btnSave.setEnabled(true);
			btnDelete.setEnabled(true);
			btnSearch.setEnabled(false);
			txtCode.setReadOnly(true);
			txtCode.setFocus(true);
			modeBox.setSelectedIndex(mode);
		} else if (mode == 3) { // insert
			btnSave.setEnabled(true);
			btnDelete.setEnabled(false);
			btnSearch.setEnabled(true);
			txtCode.setReadOnly(false);
			txtCode.setFocus(true);
			modeBox.setSelectedIndex(mode);
		}

	}

	public int getMode() {
		return mode;
	}

	// @Override
	// public void setTitle(String title) {
	// super.setTitle(title);
	// clearFields();
	// }

	abstract protected void search();

	abstract protected void refresh();

	abstract protected void update();

	abstract protected void insert();

	abstract protected void delete();

	protected void setFieldsHandler() {
		for (Widget obj : this.getChildren()) {
			if (obj instanceof ListBox) {
				((ListBox) obj).addChangeHandler(changeHandler);
			} if (obj instanceof DoubleBox) {
				((DoubleBox) obj).addChangeHandler(changeHandler);
			} else if (obj instanceof TextBox) {
				((TextBox) obj).addChangeHandler(changeHandler);
			} else if (obj instanceof TextArea) {
				((TextArea) obj).addChangeHandler(changeHandler);
			} else if (obj instanceof CheckBox) {
				((CheckBox) obj).addClickHandler(new ClickHandler() {
					@Override
					public void onClick(ClickEvent event) {
						changeHandler.onChange(null);
					}
				});
			}
		}

	}

	protected void clearFields() {
		setMode(0);
	}

	protected void setFields() {
		setMode(1);
	}

	abstract protected void getFields();

	abstract protected String getReportFile();

	abstract protected Map<String, Object> genReportParams();

	protected final ChangeHandler changeHandler = new ChangeHandler() {
		@Override
		public void onChange(ChangeEvent event) {
			if (getMode() == 1)
				setMode(2);
			else if (getMode() == 0)
				setMode(3);
		}
	};

	protected void report() {
		if (getReportFile() != null) {
			Library.getService().fillReport(getReportFile(), genReportParams(),
					reportCallback);
		} else
			Window.alert("ยังไม่ได้รับรายงาน");
	}

	public void callReportApplet(String sessionId) {
		Window.open(Window.Location.getPath()
				+ "applet/report.jsp?sessionReport=" + sessionId, "รายงาน",
				"features");
	}

	// protected final ChangeHandler changeHandler = new ChangeHandler() {
	// @Override
	// public void onChange(ChangeEvent event) {
	// btnSave.setEnabled(true);
	// btnInsert.setEnabled(false);
	// btnDelete.setEnabled(false);
	// }
	// };

	public DataForm() {
		setSize("900px", "500px");

		horizontalPanel = new HorizontalPanel();
		horizontalPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
		horizontalPanel.setSpacing(10);
		horizontalPanel.setBorderWidth(1);
		add(horizontalPanel, 10, 10);
		horizontalPanel.setSize("100px", "47px");

		btnSave = new Button("บันทึก");
		horizontalPanel.add(btnSave);
		btnSave.setSize("80px", "25px");
		btnSave.setEnabled(true);
		//
		// btnInsert = new Button("สร้าง");
		// horizontalPanel.add(btnInsert);
		// btnInsert.setSize("80px", "25px");

		btnDelete = new Button("ลบ");
		horizontalPanel.add(btnDelete);
		btnDelete.setEnabled(true);
		btnDelete.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				delete();
			}
		});
		btnDelete.setSize("80px", "25px");

		btnReport = new Button("รายงาน");
		btnReport.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				report();
			}
		});
		horizontalPanel.add(btnReport);
		btnReport.setSize("80px", "25px");
		// btnInsert.addClickHandler(new ClickHandler() {
		// public void onClick(ClickEvent event) {
		// btnInsert.setEnabled(false);
		// btnSave.setEnabled(true);
		// btnDelete.setEnabled(false);
		// btnSearch.setEnabled(true);
		// clearFields();
		// }
		// });
		btnSave.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (mode == 2) {
					update();
				} else {
					insert();
				}
				//clearFields();
			}
		});

		lbCode = new Label("รหัส");
		add(lbCode, 20, 74);
		lbCode.setSize("100px", "30px");

		txtCode = new TextBox();

		txtCode.addKeyDownHandler(new KeyDownHandler() {
			@Override
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					if (txtCode.getText() != null
							&& !txtCode.getText().equals("")) {
						refresh();
					} else {
						setMode(3);
					}
					// event.preventDefault();
				} else if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
					clearFields();
					// event.preventDefault();
				} else if (event.isControlKeyDown()
						&& event.getNativeKeyCode() == ' ') {
					search();
					// event.preventDefault();
				}
			}

		});
		add(txtCode, 122, 74);
		txtCode.setSize("100px", "18px");

		btnSearch = new Button("?");
		btnSearch.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				search();
			}
		});
		add(btnSearch, 236, 74);
		btnSearch.setSize("33px", "30px");

		modeBox = new ListBox();
		modeBox.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent event) {
				setMode(modeBox.getSelectedIndex());
			}
		});
		modeBox.addItem("Clear");
		modeBox.addItem("Browse");
		modeBox.addItem("Update");
		modeBox.addItem("Insert");
		add(modeBox, 630, 25);
		modeBox.setSize("94px", "20px");
		btnReport.setEnabled(getReportFile() != null);
	}

	private AsyncCallback<String> reportCallback = new AsyncCallback<String>() {
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(String result) {
			// if (radioApplet.getValue()) {
			callReportApplet(result);
			// }
			// if (radioHTML.getValue()) {
			// Window.open(Window.Location.getPath()
			// + "servlets/htmlprint?sessionReport=" + result, "รายงาน",
			// "features");
			// }

		}
	};

	protected AsyncCallback<Boolean> insCallback = new AsyncCallback<Boolean>() {
		public void onFailure(Throwable caught) {
			Window.alert(Library.ERROR_MESSAGE);
		}

		@Override
		public void onSuccess(Boolean result) {
			if (result) {
				String oldCode = txtCode.getText();
				Window.setStatus("บันทึกลงฐานข้อมูลเรียบร้อย : " + txtCode.getText());
				Window.alert("บันทึกลงฐานข้อมูลเรียบร้อย : " + txtCode.getText());
				txtCode.setText(oldCode);
				refresh();
			} else
				Window.alert("บันทึกไม่สำเร็จ");
		}
	};

	protected AsyncCallback<Boolean> delCallback = new AsyncCallback<Boolean>() {
		public void onFailure(Throwable caught) {
			Window.alert(Library.ERROR_MESSAGE);
		}

		@Override
		public void onSuccess(Boolean result) {
			if (result) {
				WindMill.setStatus("บันทึกลงฐานข้อมูลเรียบร้อย");
				clearFields();
			} else
				Window.alert("บันทึกไม่สำเร็จ");
		}
	};
	private final ListBox modeBox;
}
